/*
 * _08LumaQQ - Java _08QQ Client
 *
 * Copyright (C) 2008 seraph <you_meng2@163.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package edu.tsinghua.lumaqq.qq;

import static org.apache.commons.codec.digest.DigestUtils.md5;

import java.util.Iterator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import edu.tsinghua.lumaqq.qq.beans.QQFriend;
import edu.tsinghua.lumaqq.qq.beans.QQUser;
import edu.tsinghua.lumaqq.qq.events.IPacketListener;
import edu.tsinghua.lumaqq.qq.events.PacketEvent;
import edu.tsinghua.lumaqq.qq.events._08QQEvent;
import edu.tsinghua.lumaqq.qq.net.IConnectionPolicy;
import edu.tsinghua.lumaqq.qq.packets.ErrorPacket;
import edu.tsinghua.lumaqq.qq.packets.PacketParseException;
import edu.tsinghua.lumaqq.qq.packets._08BasicInPacket;
import edu.tsinghua.lumaqq.qq.packets._08InPacket;
import edu.tsinghua.lumaqq.qq.packets._08OutPacket;
import edu.tsinghua.lumaqq.qq.packets.in.AddFriendAuthResponseReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.AddFriendExReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.AdvancedSearchUserReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.AuthQuestionOpReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.ChangeStatusReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.ClusterCommandReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.DeleteFriendReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.DownloadGroupFriendReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.FriendChangeStatusPacket;
import edu.tsinghua.lumaqq.qq.packets.in.FriendDataOpReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.FriendLevelOpReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.GetFriendListReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.GetKeyReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.GetUserInfoReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.GroupDataOpReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.PrivacyDataOpReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.ReceiveIMPacket;
import edu.tsinghua.lumaqq.qq.packets.in.RemoveSelfReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.SearchUserReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.SendIMReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.SendSMSReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.SignatureOpReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.SystemNotificationPacket;
import edu.tsinghua.lumaqq.qq.packets.in.TempSessionOpReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.UnknownInPacket;
import edu.tsinghua.lumaqq.qq.packets.in.UploadGroupFriendReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.UserPropertyOpReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in.WeatherOpReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in._08._08AuthInfoOpReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in._08._08AuthorizeReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in._08._08FirstLoginReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in._08._08GetOnlineOpReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in._08._08InputStatusPacket;
import edu.tsinghua.lumaqq.qq.packets.in._08._08KeepAliveReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in._08._08LoginKeyReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in._08._08LoginReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in._08._08LoginToken1ReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in._08._08LoginToken2ReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in._08._08ModifyInfoReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.in._08._08TouchLoginReplyPacket;
import edu.tsinghua.lumaqq.qq.packets.out.ClusterCommandPacket;
import edu.tsinghua.lumaqq.qq.packets.out.SendIMPacket;
import edu.tsinghua.lumaqq.qq.packets.out._08._08ModifyInfoPacket;

/**
 * 这个类处理基本协议族包事件
 *
 * @author luma
 */
class _08BasicFamilyProcessor implements IPacketListener {
    // Log对象

    static Log log = LogFactory.getLog(_08BasicFamilyProcessor.class);

    // QQ客户端
    private _08QQClient client;
    // QQ用户，我们将在收到登陆包后设置user不为null，所以如果user为null意味着尚未登陆
    private QQUser user;
    private IConnectionPolicy policy;
    // Touch失败时所获取的推荐服务器地址
    public byte[] serverIp = new byte[4];

    public _08BasicFamilyProcessor(_08QQClient client) {
        this.client = client;
        this.user = null;
    }

    // 处理登陆应答
    private void processLoginReply(_08BasicInPacket in) {
        _08QQEvent e;
        _08LoginReplyPacket packet = (_08LoginReplyPacket) in;
        // 开始判断应答内容
        switch (packet.replyCode) {
            case _08QQ.QQ_REPLY_OK:
                log.debug("登陆成功，用户IP为: " + Util.getIpStringFromBytes(packet.ip) + " 端口: " + packet.port);
                // 登陆成功的话我们就设置用户的一些信息，然后触发事件
                user.setSessionKey(packet.sessionKey);
                user.setIp(packet.ip);
                user.setPort(packet.port);
                user.setServerPort(packet.serverPort);
                user.setLoginTimeRude(packet.loginTimeRude);
                user.setLoginTime(packet.loginTime);
                user.setLastLoginIp(packet.lastLoginIp);
                user.setLastLoginTime(packet.lastLoginTime);
                user.setClientKey(packet.clientKey);
                user.setAuthToken(packet.authToken);
                user.setUserQQ(packet.userQQ);
                user.setServerIp(packet.serverIp);
                // 得到文件传输密钥
                byte[] b = new byte[4 + _08QQ.QQ_LENGTH_KEY];
                b[0] = (byte) ((user.getQQ() >>> 24) & 0xFF);
                b[1] = (byte) ((user.getQQ() >>> 16) & 0xFF);
                b[2] = (byte) ((user.getQQ() >>> 8) & 0xFF);
                b[3] = (byte) (user.getQQ() & 0xFF);
                System.arraycopy(user.getSessionKey(), 0, b, 4, _08QQ.QQ_LENGTH_KEY);
                user.setFileSessionKey(md5(b));
                // 触发事件
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.LOGIN_OK;
                client.fireQQEvent(e);
                break;
            case _08QQ.QQ_REPLY_LOGIN_FAIL:
                log.debug("登录失败: " + packet.replyMessage);
                // 如果是密码错误，触发事件
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.LOGIN_FAIL;
                client.fireQQEvent(e);
                break;
            case _08QQ.QQ_REPLY_LOGIN_REDIRECT:
                log.debug("登陆重定向");
                if (Util.isIpZero(packet.redirectIp)) {
                    log.debug("地址重定向到0，随机选取其他服务器再登录");
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.LOGIN_REDIRECT_NULL;
                    client.fireQQEvent(e);
                } else {
                    // 如果是登陆重定向，继续登陆
                    client.setLoginRedirect(true);
                    try {// changed by luna ，以前这里是login(server,port);

                        log.debug("重定向IP为：" + Util.getIpStringFromBytes(packet.redirectIp));
                        client.sendTouch(Util.getIpStringFromBytes(packet.redirectIp),
                                packet.redirectPort);
                    } catch (Exception e1) {
                        log.error(e1.getMessage());
                    }
                }
                break;
            case _08QQ.QQ_LOGIN_FAIL://登录失败

                log.debug("登录失败，继续登录");
                try {
                    String suggestIP = null;
                    if (user.getSuggestServerIp() != null) {
                        suggestIP = Util.getIpStringFromBytes(user.getSuggestServerIp());
                    }
                    if (suggestIP != null) {
                        if (user.isUdp()) {
                            client.sendTouch(suggestIP, 8000);
                        } else {
                            client.sendTouch(suggestIP, 80);
                        }
                    } else {
                        client.sendTouch();
                    }
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
                break;
            case _08QQ.QQ_CMD_PASSWORD_ERROR:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.PASSWORD_ERROR;
                break;
            default:
                log.debug("未知登陆错误");
                // 如果是其他未知错误，触发事件
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.LOGIN_UNKNOWN_ERROR;
                client.fireQQEvent(e);
                break;
        }
    }

    /**
     * 判断包是否时登录前可以出现的包，有些包是在登录前可以处理的，如果不是，应该缓存起来等
     * 到登录成功后再处理，不过但是在实际中观察发现，登录之前收到的东西基本没用，可以不管(已过时)
     *
     * @param cmd
     * @return
     * @change by luna 判断是否为需要处理的包，不一定登陆之前的包就一定不用处理
     */
    private boolean isPreLoginPacket(_08BasicInPacket in) {
        switch (in.getCommand()) {
            //case _08QQ.QQ_CMD_GET_LOGIN_TOKEN:
            case _08QQ.QQ_CMD_LOGIN:
            case _08QQ.QQ_CMD_TOUCH:
            case _08QQ.QQ_CMD_LOGIN_TOKEN_1:
            case _08QQ.QQ_CMD_LOGIN_TOKEN_2:
            case _08QQ.QQ_CMD_CHECK_PASSWORD:
            case _08QQ.QQ_CMD_FIRST_LOGIN:
                return true;
            case _08QQ.QQ_CMD_UNKNOWN:
                return in instanceof ErrorPacket;
            default:
                return false;
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see edu.tsinghua.lumaqq.protocol.qq.PacketListener#packetArrived(edu.tsinghua.lumaqq.protocol.qq.PacketEvent)
     */
    public void packetArrived(PacketEvent e) {
        _08BasicInPacket in = (_08BasicInPacket) e.getSource();
        if (in instanceof UnknownInPacket) {
            log.debug("收到一个未知格式包");
            log.info("包的协议族为：" + in.getFamily());
            log.debug("包的描述性命令为：" + Util.convertByteToHexString(Util.convertCharToBytes(in.getCommand())));
            return;
        }

        // 显示调试信息
        if (in instanceof ErrorPacket) {
            ErrorPacket packet = (ErrorPacket) in;
            log.debug("开始处理错误通知包，错误类型：" + in);
            log.debug("Error Code 为：" + packet.errorMessage);
        } else {
            log.debug("开始处理" + in.toString());

            // 检查目前是否已经登录
        }
        if (user == null || !user.isLoggedIn()) {
            /*
             * 按理说应该把在登陆之前时收到的包缓存起来，但是在实际中观察发现，登录之前收到的
             * 东西基本没用，所以在这里不做任何事情，简单的抛弃这个包
             */
            if (!isPreLoginPacket(in)) {
                return;
            }
        }

        // 这里检查是不是服务器发回的确认包
        // 为什么要检查这个呢，因为有些包是服务器主动发出的，对于这些包我们是不需要
        // 从超时发送队列中移除的，如果是服务器的确认包，那么我们就需要把超时发送队列
        // 中包移除
        switch (in.getCommand()) {
            // 这三种包是服务器先发出的，我们要确认
            case _08QQ.QQ_CMD_RECV_IM:
            case _08QQ.QQ_CMD_RECV_MSG_SYS:
            case _08QQ.QQ_CMD_RECV_MSG_FRIEND_CHANGE_STATUS:
                break;
                // 未知命令忽略掉
            case _08QQ.QQ_CMD_UNKNOWN:
                break;
                // 其他情况我们删除超时队列中的包
            default:
                client.removeResendPacket(in);
                log.debug("包" + (int) in.getSequence() + "的确认已经收到，将不再发送");
                break;
        }

        // 现在开始判断包的类型，作出相应的处理
        policy = client.getConnectionPolicy(in);
        if (policy == null) {
            return;
        }
        switch (in.getCommand()) {
            case _08QQ.QQ_CMD_TOUCH:// 由seraph添加

                this.user = client.getUser();
                processTouchLogin(in);
                break;
            case _08QQ.QQ_CMD_LOGIN_TOKEN_1:// 由seraph添加

                processLoginToken1(in);
                break;
            case _08QQ.QQ_CMD_LOGIN_TOKEN_2:// 由seraph添加

                processLoginToken2(in);
                break;
            case _08QQ.QQ_CMD_CHECK_PASSWORD:// 由seraph添加

                processLoginKey(in);
                break;

                /*case _08QQ.QQ_CMD_GET_LOGIN_TOKEN:
                this.user = client.getUser();
                processGetLoginTokenReply(in);
                break;	*/
            case _08QQ.QQ_CMD_KEEP_ALIVE:
                processKeepAliveReply(in);
                break;
            case _08QQ.QQ_CMD_MODIFY_INFO:
                processModifyInfoReply(in);
                break;
            case _08QQ.QQ_CMD_SEARCH_USER:
                processSearchUserReply(in);
                break;
            case _08QQ.QQ_CMD_ADD_FRIEND_EX:
                processAddFriendExReply(in);
                break;
            case _08QQ.QQ_CMD_AUTH_INFO_OP:
                processAuthInfoOpReply(in);
                break;
            case _08QQ.QQ_CMD_AUTH_QUESTION_OP:
                processAuthQuestionOpReply(in);
                break;
            case _08QQ.QQ_CMD_DELETE_FRIEND:
                processDeleteFriendReply(in);
                break;
            case _08QQ.QQ_CMD_REMOVE_SELF:
                processRemoveSelfReply(in);
                break;
            case _08QQ.QQ_CMD_ADD_FRIEND_AUTH:
                processAddFriendAuthReply(in);
                break;
            case _08QQ.QQ_CMD_GET_USER_INFO:
                processGetUserInfoReply(in);
                break;
            case _08QQ.QQ_CMD_CHANGE_STATUS:
                processChangeStatusReply(in);
                break;
            case _08QQ.QQ_CMD_SEND_IM:
                processSendIMReply(in);
                break;
            case _08QQ.QQ_CMD_RECV_IM:
                processInputStatusIM(in);
                processReceiveIM(in);
                break;
            case _08QQ.QQ_CMD_SEND_SMS:
                processSendSMSReply(in);
                break;
            case _08QQ.QQ_CMD_LOGIN:
                processLoginReply(in);
                break;
            case _08QQ.QQ_CMD_FIRST_LOGIN:
                processFirstLoginReply(in);
                break;
            case _08QQ.QQ_CMD_GET_FRIEND_LIST:
                processGetFriendListReply(in);
                break;
            case _08QQ.QQ_CMD_GET_ONLINE_OP:
                processGetFriendOnlineReply(in);
                break;
            case _08QQ.QQ_CMD_RECV_MSG_SYS:
                processSystemNotification(in);
                break;
            case _08QQ.QQ_CMD_RECV_MSG_FRIEND_CHANGE_STATUS:
                processFriendChangeStatus(in);
                break;
            case _08QQ.QQ_CMD_UPLOAD_GROUP_FRIEND:
                processUploadGroupFriendReply(in);
                break;
            case _08QQ.QQ_CMD_DOWNLOAD_GROUP_FRIEND:
                processDownloadGroupFriendReply(in);
                break;
            case _08QQ.QQ_CMD_GROUP_DATA_OP:
                processGroupNameOpReply(in);
                break;
            case _08QQ.QQ_CMD_FRIEND_DATA_OP:
                processFriendDataOpReply(in);
                break;
            case _08QQ.QQ_CMD_CLUSTER_CMD:
                processClusterCommandReply(in);
                break;
            case _08QQ.QQ_CMD_REQUEST_KEY:
                processRequestKeyReply(in);
                break;
            case _08QQ.QQ_CMD_ADVANCED_SEARCH:
                processAdvancedSearchReply(in);
                break;
            case _08QQ.QQ_CMD_AUTHORIZE:
                processAuthorizeReply(in);
                break;
            case _08QQ.QQ_CMD_SIGNATURE_OP:
                processSignatureOpReply(in);
                break;
            case _08QQ.QQ_CMD_USER_PROPERTY_OP:
                processUserPropertyOpReply(in);
                break;
            case _08QQ.QQ_CMD_FRIEND_LEVEL_OP:
                processFriendLevelOpReply(in);
                break;
            case _08QQ.QQ_CMD_WEATHER_OP:
                processWeatherOpReply(in);
                break;
            case _08QQ.QQ_CMD_TEMP_SESSION_OP:
                processTempSessionOpReply(in);
                break;
            case _08QQ.QQ_CMD_PRIVACY_DATA_OP:
                processPrivacyDataOpReply(in);
                break;

            case _08QQ.QQ_CMD_UNKNOWN:
                processUnknown(in);
                break;

            default:
                break;
        }
    }

    /**
     * 处理首次登陆的回复包
     */
    private void processFirstLoginReply(_08BasicInPacket in) {
        _08FirstLoginReplyPacket packet = (_08FirstLoginReplyPacket) in;
        _08QQEvent e = new _08QQEvent(packet);
        e.type = _08QQEvent.FIRST_PRE_LOGIN;
        client.fireQQEvent(e);
    }

    /**
     * 处理登陆密匙
     *
     * @param in
     * @author luna
     */
    private void processLoginKey(_08BasicInPacket in) {
        _08LoginKeyReplyPacket packet = (_08LoginKeyReplyPacket) in;
        _08QQEvent e = new _08QQEvent(packet);
        switch (packet.replyCode) {
            case _08QQ.QQ_REPLY_OK:
                user.setLoginKey(packet.key);
                user.setLoginToken(packet.loginToken);
                e.type = _08QQEvent.LOGIN_KEY_CHECKED;
                break;
            case _08QQ.QQ_CMD_PASSWORD_ERROR:
            case _08QQ.QQ_CMD_NEED_ACTIVATE:
                log.info("用户名或密码错误");
                e.type = _08QQEvent.PASSWORD_ERROR;
                break;
            default:
                e.type = _08QQEvent.LOGIN_UNKNOWN_ERROR;
        }
        client.fireQQEvent(e);
    }

    /**
     * 处理登陆令牌2
     *
     * @param in
     * @author luna
     */
    private void processLoginToken2(_08BasicInPacket in) {
        _08QQEvent e;
        _08LoginToken2ReplyPacket packet = (_08LoginToken2ReplyPacket) in;
        switch (packet.replyCode) {
            case _08QQ.QQ_REPLY_OK:
                log.debug("得到登录令牌成功");
                user.setTempToken(packet.loginToken2);
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.LOGIN_TOKEN_2_OK;
                client.fireQQEvent(e);
                break;
            case _08QQ.QQ_REPLY_LOGIN_NEED_VERIFY:
                log.debug("需要输入验证码");
                user.setTempToken(packet.loginToken2);
                user.setPuzzleToken(packet.nextImageToken);
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.LOGIN_NEED_VERIFY;
                client.fireQQEvent(e);
                break;
        }
    }

    /**
     * 处理登陆令牌1
     *
     * @param in
     * @author seraph
     */
    private void processLoginToken1(_08BasicInPacket in) {
        _08QQEvent e;
        _08LoginToken1ReplyPacket packet = (_08LoginToken1ReplyPacket) in;
        if (packet.loginToken1 != null) {
            user.setLoginToken(packet.loginToken1);
        }
        e = new _08QQEvent(packet);
        e.type = _08QQEvent.LOGIN_TOKEN_1;
        client.fireQQEvent(e);
    }

    private void processInputStatusIM(_08BasicInPacket in) {
        _08QQEvent e;
        if (in instanceof _08InputStatusPacket) {
            _08InputStatusPacket packet = (_08InputStatusPacket) in;
            if (packet.flag != 0) {
                log.info("用户正在输入信息");
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.INPUT_STATUS;
            }
        }
    }

    /**
     * ************************************************************************
     *
     * @param in
     * @author seraph
     * <p/>
     * 处理Touch包事件,用途是检测是否有推荐服务器的地址
     */
    private void processTouchLogin(_08BasicInPacket in) {
        _08QQEvent e;
        _08TouchLoginReplyPacket packet = (_08TouchLoginReplyPacket) in;
        if (packet.serverIp != null && packet.serverIp.length > 0) {
            // 设置推荐服务器地址，前提是Touch失败,第一次一般都是Touch失败，因为我设定的服务器是随便定的
            if (user != null) {
                if (user.isUdp()) {

                    log.debug("开始连接推荐服务器--" + Util.getIpStringFromBytes(packet.serverIp));
                    client.sendTouch(
                            Util.getIpStringFromBytes(packet.serverIp), 8000);
                    user.setSuggestServerIp(packet.serverIp);
                    return;
                } else {
                    log.debug("开始连接推荐服务器--" + Util.getIpStringFromBytes((packet.serverIp)));
                    client.sendTouch(
                            Util.getIpStringFromBytes(packet.serverIp), 80);
                    user.setSuggestServerIp(packet.serverIp);
                    return;
                }
            }
        }
        e = new _08QQEvent(packet);
        e.type = _08QQEvent.LOGIN_TOUCH;
        client.fireQQEvent(e);

    }

    private void processAuthQuestionOpReply(_08BasicInPacket in) {
        _08QQEvent e;
        AuthQuestionOpReplyPacket packet = (AuthQuestionOpReplyPacket) in;
        switch (packet.subCommand) {
            case _08QQ.QQ_SUB_CMD_GET_QUESTION:
                e = new _08QQEvent(packet);
                e.type = packet.replyCode == _08QQ.QQ_REPLY_OK ? _08QQEvent.FRIEND_GET_AUTH_QUESTION_OK
                        : _08QQEvent.FRIEND_GET_AUTH_QUESTION_FAIL;
                client.fireQQEvent(e);
                break;
            case _08QQ.QQ_SUB_CMD_ANSWER_QUESTION:
                e = new _08QQEvent(packet);
                e.type = packet.replyCode == _08QQ.QQ_REPLY_OK ? _08QQEvent.FRIEND_RIGHT_ANSWER
                        : _08QQEvent.FRIEND_WRONG_ANSWER;
                client.fireQQEvent(e);
                break;
        }
    }

    /**
     * 处理验证信息
     *
     * @param in
     */
    private void processAuthInfoOpReply(_08BasicInPacket in) {
        _08QQEvent e;
        _08AuthInfoOpReplyPacket packet = (_08AuthInfoOpReplyPacket) in;
        switch (packet.subCommand) {
            case _08QQ.QQ_SUB_CMD_GET_AUTH_INFO:
                log.debug("用户验证信息已经被获取！");
                e = new _08QQEvent(packet);
                switch (packet.subsubCommand) {
                    case _08QQ.QQ_SUB_SUB_CMD_GET_FRIEND_AUTH_INFO:
                        user.setAuthToken(packet.authInfo);
                        e.type = _08QQEvent.FRIEND_GET_AUTH_INFO_OK;
                        break;
                    case _08QQ.QQ_SUB_SUB_CMD_GET_SIGNATURE_AUTH_INFO:
                        user.setAuthToken(packet.authInfo);
                        e.type = _08QQEvent.USER_GET_USER_INFO_AUTH_INFO_OK;
                        break;
                    case _08QQ.QQ_SUB_SUB_CMD_GET_CLUSTER_AUTH_INFO:
                        log.debug("加入群命令正在被执行！");
                        user.setAuthToken(packet.authInfo);
                        e.type = _08QQEvent.USER_GET_JOIN_CLUSTER_AUTH_TOKEN_OK;
                        break;
                    case _08QQ.QQ_SUB_SUB_CMD_GET_DELETE_USER_AUTH_INFO:
                        log.debug("删除好友命令正在被执行！");
                        user.setAuthToken(packet.authInfo);
                        e.type = _08QQEvent.USER_GET_DELETE_FRIEND_AUTH_INFO_OK;
                        break;
                    case _08QQ.QQ_SUB_SUB_CMD_GET_USER_TEMP_SESSION_AUTH_INFO:
                        user.setAuthToken(packet.authInfo);
                        e.type = _08QQEvent.USER_GET_TEMP_SESSION_AUTH_INFO_OK;
                        break;
                    default:
                        user.setImageUrl(Util.getString(packet.authInfo));
                        e.type = _08QQEvent.FRIEND_GET_AUTH_INFO_FROM_URL;
                        break;
                }
                client.fireQQEvent(e);
                break;
            case _08QQ.QQ_SUB_CMD_SUBMIT_AUTH_INFO_BY_VERTIFYCODE:
                e = new _08QQEvent(packet);
                user.setAuthToken(packet.authInfo);
                e.type = packet.replyCode == _08QQ.QQ_REPLY_OK ? _08QQEvent.FRIEND_SUBMIT_AUTO_INFO_OK
                        : _08QQEvent.FRIEND_SUBMIT_AUTO_INFO_FAIL;
                client.fireQQEvent(e);
                break;
        }
    }

    /**
     * 处理隐私选项操作回复包
     *
     * @param in
     */
    private void processPrivacyDataOpReply(_08BasicInPacket in) {
        _08QQEvent e;
        PrivacyDataOpReplyPacket packet = (PrivacyDataOpReplyPacket) in;
        switch (packet.replyCode) {
            case _08QQ.QQ_REPLY_OK:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.USER_PRIVACY_DATA_OP_OK;
                client.fireQQEvent(e);
                break;
            default:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.USER_PRIVACY_DATA_OP_FAIL;
                client.fireQQEvent(e);
                break;
        }
    }

    /**
     * 处理临时会话回复包
     *
     * @param in
     */
    private void processTempSessionOpReply(_08BasicInPacket in) {
        _08QQEvent e;
        TempSessionOpReplyPacket packet = (TempSessionOpReplyPacket) in;
        switch (packet.replyCode) {
            case _08QQ.QQ_REPLY_OK:
            case _08QQ.QQ_REPLY_MAYBE_OFFLINE:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.IM_TEMP_SESSION_SEND_OK;
                client.fireQQEvent(e);
                break;
            default:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.IM_TEMP_SESSION_SEND_FAIL;
                client.fireQQEvent(e);
                break;
        }
    }

    /**
     * 处理天气预报操作回复包
     *
     * @param in
     */
    private void processWeatherOpReply(_08BasicInPacket in) {
        WeatherOpReplyPacket packet = (WeatherOpReplyPacket) in;
        _08QQEvent e;
        switch (packet.replyCode) {
            case _08QQ.QQ_REPLY_OK:
                e = new _08QQEvent(packet);
                if (packet.province == null) {
                    e.type = _08QQEvent.USER_WEATHER_GET_FAIL;
                } else {
                    e.type = _08QQEvent.USER_WEATHER_GET_OK;
                }
                client.fireQQEvent(e);
                break;
            default:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.USER_WEATHER_GET_FAIL;
                client.fireQQEvent(e);
                break;
        }
    }

    /**
     * 处理发送短信回复事件
     *
     * @param in
     */
    private void processSendSMSReply(_08BasicInPacket in) {
        SendSMSReplyPacket packet = (SendSMSReplyPacket) in;
        _08QQEvent e = new _08QQEvent(packet);
        e.type = _08QQEvent.SMS_SEND_OK;
        client.fireQQEvent(e);
    }

    /**
     * 处理好友等级回复包
     *
     * @param in
     */
    private void processFriendLevelOpReply(_08BasicInPacket in) {
        FriendLevelOpReplyPacket packet = (FriendLevelOpReplyPacket) in;
        _08QQEvent e = new _08QQEvent(packet);
        e.type = _08QQEvent.FRIEND_GET_LEVEL_OK;
        client.fireQQEvent(e);
    }

    /**
     * 处理用户属性回复包
     *
     * @param in
     */
    private void processUserPropertyOpReply(_08BasicInPacket in) {
        UserPropertyOpReplyPacket packet = (UserPropertyOpReplyPacket) in;
        _08QQEvent e = new _08QQEvent(packet);
        e.type = _08QQEvent.USER_GET_PROPERTY_OK;
        client.fireQQEvent(e);
    }

    /**
     * 处理个性签名操作回复包
     *
     * @param in
     */
    private void processSignatureOpReply(_08BasicInPacket in) {
        _08QQEvent e;
        SignatureOpReplyPacket packet = (SignatureOpReplyPacket) in;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            switch (packet.subCommand) {
                case _08QQ.QQ_SUB_CMD_MODIFY_SIGNATURE:
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.USER_MODIFY_SIGNATURE_OK;
                    client.fireQQEvent(e);
                    break;
                case _08QQ.QQ_SUB_CMD_DELETE_SIGNATURE:
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.USER_DELETE_SIGNATURE_OK;
                    client.fireQQEvent(e);
                    break;
                case _08QQ.QQ_SUB_CMD_GET_SIGNATURE:
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.USER_GET_SIGNATURE_OK;
                    client.fireQQEvent(e);
                    break;
            }
        } else {
            switch (packet.subCommand) {
                case _08QQ.QQ_SUB_CMD_MODIFY_SIGNATURE:
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.USER_MODIFY_SIGNATURE_FAIL;
                    client.fireQQEvent(e);
                    break;
                case _08QQ.QQ_SUB_CMD_DELETE_SIGNATURE:
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.USER_DELETE_SIGNATURE_FAIL;
                    client.fireQQEvent(e);
                    break;
                case _08QQ.QQ_SUB_CMD_GET_SIGNATURE:
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.USER_GET_SIGNATURE_FAIL;
                    client.fireQQEvent(e);
                    break;
            }
        }
    }

    /**
     * 处理认证消息发送包
     *
     * @param in
     */
    private void processAuthorizeReply(_08BasicInPacket in) {
        _08QQEvent e;
        _08AuthorizeReplyPacket packet = (_08AuthorizeReplyPacket) in;
        switch (packet.replyCode) {
            case _08QQ.QQ_AUTHORIZE_REPLY_OK:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.FRIEND_AUTHORIZE_SEND_OK;
                client.fireQQEvent(e);
                break;
            default:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.FRIEND_AUTHORIZE_SEND_FAIL;
                client.fireQQEvent(e);
                break;
        }
    }

    /**
     * 处理未知命令包，有些和协议无关的包也使用这个命令，比如ErrorPacket
     *
     * @param in
     */
    private void processUnknown(_08BasicInPacket in) {
        _08QQEvent e = null;
        if (in instanceof ErrorPacket) {
            ErrorPacket error = (ErrorPacket) in;
            switch (error.errorCode) {
                case ErrorPacket.ERROR_CONNECTION_BROKEN:
                    e = new _08QQEvent(error);
                    e.type = _08QQEvent.ERROR_CONNECTION_BROKEN;
                    break;
                case ErrorPacket.ERROR_TIMEOUT:
                    _08OutPacket packet = error.timeoutPacket;
                    switch (packet.getCommand()) {
                        case _08QQ.QQ_CMD_KEEP_ALIVE:
                            // 说明连接已经丢失
                            e = new _08QQEvent(packet);
                            e.type = _08QQEvent.USER_KEEP_ALIVE_FAIL;
                            break;
                        default:
                            e = new _08QQEvent(packet);
                            e.type = _08QQEvent.SYS_TIMEOUT;
                            e.operation = packet.getCommand();
                            break;
                    }
                    break;
                case ErrorPacket.ERROR_PROXY:
                    e = new _08QQEvent(error);
                    e.type = _08QQEvent.ERROR_PROXY;
                    break;
                case ErrorPacket.ERROR_NETWORK:
                    e = new _08QQEvent(error);
                    e.type = _08QQEvent.ERROR_NETWORK;
                    break;
                case ErrorPacket.RUNTIME_ERROR:
                    e = new _08QQEvent(error);
                    e.type = _08QQEvent.ERROR_RUNTIME;
                    break;
            }
        }

        if (e != null) {
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理高级搜索的回复包
     *
     * @param in
     */
    private void processAdvancedSearchReply(_08BasicInPacket in) {
        _08QQEvent e;
        AdvancedSearchUserReplyPacket packet = (AdvancedSearchUserReplyPacket) in;

        if (packet.replyCode == _08QQ.QQ_REPLY_OK && !packet.finished) {
            log.debug("高级搜索成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.USER_ADVANCED_SEARCH_OK;
            client.fireQQEvent(e);
        } else if (packet.replyCode == _08QQ.QQ_REPLY_ADVANCED_SEARCH_END || packet.finished) {
            log.debug("高级搜索完毕");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.USER_ADVANCED_SEARCH_END;
            client.fireQQEvent(e);
        } else {
            log.debug("高级搜索返回未知回复码");
        }
    }

    /**
     * @deprecated
     * 处理请求登录令牌的回复包
     *
     * @param in
     */
    /*    private void processGetLoginTokenReply(_08BasicInPacket in) {
        _08QQEvent e;
        GetLoginTokenReplyPacket packet = (GetLoginTokenReplyPacket) in;

        switch (packet.replyCode) {
            case _08QQ.QQ_REPLY_OK:
                log.debug("得到登录令牌成功");
                user.setLoginToken(packet.token);
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.LOGIN_GET_TOKEN_OK;
                client.fireQQEvent(e);
                break;
            case _08QQ.QQ_REPLY_LOGIN_NEED_VERIFY:
                log.debug("需要输入验证码");
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.LOGIN_NEED_VERIFY;
                client.fireQQEvent(e);
                break;
        }
    }*/

    /**
     * 处理群命令的回复包
     *
     * @param in
     * @throws PacketParseException
     */
    private void processClusterCommandReply(_08BasicInPacket in) {
        ClusterCommandReplyPacket packet = (ClusterCommandReplyPacket) in;

        switch (packet.subCommand) {
            case _08QQ.QQ_CLUSTER_CMD_CREATE_CLUSTER:
                processClusterCreateReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_ACTIVATE_CLUSTER:
                processClusterActivateReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_ACTIVATE_TEMP:
                processClusterActivateTempReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_MODIFY_MEMBER:
                processClusterModifyMember(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_GET_CLUSTER_INFO:
                processClusterGetInfoReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_GET_ONLINE_MEMBER:
                processClusterGetOnlineMemberReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_GET_MEMBER_INFO:
                processClusterGetMemberInfoReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_EXIT_CLUSTER:
                processClusterExitReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_DISMISS_CLUSTER:
                processClusterDismissReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_JOIN_CLUSTER:
                processClusterJoinReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_JOIN_CLUSTER_AUTH:
                processClusterJoinAuthReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_MODIFY_CLUSTER_INFO:
                processClusterModifyInfoReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_SEARCH_CLUSTER:
                processClusterSearchReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_SEND_IM_EX:
                processClusterSendIMExReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_CREATE_TEMP:
                processClusterCreateTempClusterReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_SEND_TEMP_IM:
                processClusterSendTempClusterIMReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_EXIT_TEMP:
                processClusterExitTempClusterReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_GET_TEMP_INFO:
                processClusterGetTempClusterInfoReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_MODIFY_TEMP_MEMBER:
                processClusterModifyTempClusterMemberReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_SUB_CLUSTER_OP:
                processClusterSubClusterOpReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_UPDATE_ORGANIZATION:
                processUpdateOrganizationReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_COMMIT_ORGANIZATION:
                processCommitOrganizationReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_COMMIT_MEMBER_ORGANIZATION:
                processCommitMemberOrganizationReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_MODIFY_TEMP_INFO:
                processModifyTempClusterInfoReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_GET_CARD_BATCH:
                processGetCardBatchReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_GET_CARD:
                processGetCardReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_MODIFY_CARD:
                processModifyCardReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_SET_ROLE:
                processSetRoleReply(packet);
                break;
            case _08QQ.QQ_CLUSTER_CMD_TRANSFER_ROLE:
                processTransferRoleReply(packet);
                break;
        }
    }

    /**
     * 处理激活临时群回复包
     *
     * @param packet
     */
    private void processClusterActivateTempReply(
            ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("临时群激活成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_ACTIVATE_TEMP_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("群激活失败");
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_ACTIVATE_TEMP_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理解散群回复包
     *
     * @param packet
     */
    private void processClusterDismissReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_DISMISS_OK;
            client.fireQQEvent(e);
        } else {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_DISMISS_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理转让身份回复包
     *
     * @param packet
     */
    private void processTransferRoleReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_TRANSFER_ROLE_OK;
            client.fireQQEvent(e);
        } else {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_TRANSFER_ROLE_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理设置成员角色回复包
     *
     * @param packet
     */
    private void processSetRoleReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_SET_ROLE_OK;
            client.fireQQEvent(e);
        } else {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_SET_ROLE_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理修改群名片回复包
     *
     * @param packet
     */
    private void processModifyCardReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_MODIFY_CARD_OK;
            client.fireQQEvent(e);
        } else {
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_MODIFY_CARD_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理得到单个成员群名片信息回复包
     *
     * @param packet
     */
    private void processGetCardReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_GET_CARD_OK;
            client.fireQQEvent(e);
        } else {
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_GET_CARD_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理批量得到群名片回复包
     *
     * @param packet
     */
    private void processGetCardBatchReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_GET_CARDS_OK;
            client.fireQQEvent(e);
        } else {
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_GET_CARDS_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理修改临时群信息回复包
     *
     * @param packet
     */
    private void processModifyTempClusterInfoReply(
            ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_MODIFY_TEMP_INFO_OK;
            client.fireQQEvent(e);
        } else {
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_MODIFY_TEMP_INFO_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理提交成员分组情况回复包
     *
     * @param packet
     */
    private void processCommitMemberOrganizationReply(
            ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_COMMIT_MEMBER_ORG_OK;
            client.fireQQEvent(e);
        } else {
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_COMMIT_MEMBER_ORG_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理提交组织架构回复包
     *
     * @param packet
     */
    private void processCommitOrganizationReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_COMMIT_ORG_OK;
            client.fireQQEvent(e);
        } else {
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_COMMIT_ORG_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理更新组织架构回复包
     *
     * @param packet
     */
    private void processUpdateOrganizationReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_UPDATE_ORG_OK;
            client.fireQQEvent(e);
        } else {
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_UPDATE_ORG_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理讨论组操作回复包
     *
     * @param packet
     */
    private void processClusterSubClusterOpReply(
            ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_SUB_OP_OK;
            client.fireQQEvent(e);
        } else {
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_SUB_OP_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理修改临时群成员的回复包
     *
     * @param packet
     */
    private void processClusterModifyTempClusterMemberReply(
            ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
        packet.clusterId = ccp.getClusterId();
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("临时群成员修改成功，群ID：" + packet.clusterId + " 父ID：" + packet.parentClusterId);
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_MODIFY_TEMP_MEMBER_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("临时群成员修改失败");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_MODIFY_TEMP_MEMBER_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理创建临时群的回复包
     *
     * @param packet
     */
    private void processClusterCreateTempClusterReply(
            ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("临时群创建成功，群ID：" + packet.clusterId + " 父ID：" + packet.parentClusterId);
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_CREATE_TEMP_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("临时群创建失败");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_CREATE_TEMP_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理修改群成员的回复包
     *
     * @param packet ClusterCommandReplyPacket
     */
    private void processClusterModifyMember(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("群成员修改成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_MODIFY_MEMBER_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("群成员修改失败");
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_MODIFY_MEMBER_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * @param packet
     */
    private void processClusterSendTempClusterIMReply(
            ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
        packet.clusterId = ccp.getClusterId();
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("临时群消息发送成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.IM_TEMP_CLUSTER_SEND_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("临时群消息发送失败");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.IM_TEMP_CLUSTER_SEND_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理扩展群消息回复包
     *
     * @param packet
     */
    private void processClusterSendIMExReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("群消息发送成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.IM_CLUSTER_SEND_EX_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("群消息发送失败");
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.IM_CLUSTER_SEND_EX_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理搜索群的回复包
     *
     * @param packet
     */
    private void processClusterSearchReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("群搜索成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_SEARCH_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("搜索群失败");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_SEARCH_FAIL;
            client.fireQQEvent(e);
        }
    }

    // 处理修改群信息的回复包
    private void processClusterModifyInfoReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("群信息修改成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_MODIFY_INFO_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("群信息修改失败");
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_MODIFY_INFO_FAIL;
            client.fireQQEvent(e);
        }
    }

    // 处理认证信息发送的回复包
    private void processClusterJoinAuthReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("认证信息发送成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_AUTH_SEND_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("认证信息发送失败");
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_AUTH_SEND_FAIL;
            client.fireQQEvent(e);
        }
    }

    // 处理加入群的回复包
    private void processClusterJoinReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            switch (packet.joinReply) {
                case _08QQ.QQ_CLUSTER_JOIN_OK:
                    log.debug("加入群成功");
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.CLUSTER_JOIN_OK;
                    client.fireQQEvent(e);
                    break;
                case _08QQ.QQ_CLUSTER_JOIN_NEED_AUTH:
                    log.debug("对方需要认证");
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.CLUSTER_JOIN_NEED_AUTH;
                    client.fireQQEvent(e);
                    break;
                case _08QQ.QQ_CLUSTER_JOIN_DENIED:
                    log.debug("对方禁止加入成员");
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.CLUSTER_JOIN_DENY;
                    client.fireQQEvent(e);
                    break;
                default:
                    log.debug("收到加入群的回复，但是回复码未知，抛弃该包");
                    break;
            }
        } else {
            log.debug("加入群失败");
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_JOIN_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * @param packet
     */
    private void processClusterExitTempClusterReply(
            ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
        packet.clusterId = ccp.getClusterId();
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("退出群成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_EXIT_TEMP_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("退出群失败");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_EXIT_TEMP_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理退出群的回复包
     *
     * @param packet
     */
    private void processClusterExitReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("退出群成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_EXIT_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("退出群失败");
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_EXIT_FAIL;
            client.fireQQEvent(e);
        }
    }

    // 处理得到群成员信息的回复包
    private void processClusterGetMemberInfoReply(
            ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("得到群成员信息成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_GET_MEMBER_INFO_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("得到群成员信息失败");
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_GET_ONLINE_MEMBER_FAIL;
            client.fireQQEvent(e);
        }
    }

    // 处理得到在线群成员的回复包
    private void processClusterGetOnlineMemberReply(
            ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("得到在线成员列表成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_GET_ONLINE_MEMBER_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("得到在线成员列表失败");
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_GET_ONLINE_MEMBER_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理得到群信息回复包
     *
     * @param packet
     */
    private void processClusterGetInfoReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("成功得到群信息，群内部ID：" + packet.clusterId + " 群名称：" + packet.info.name);
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_GET_INFO_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("得到群信息失败");
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_GET_INFO_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理得到临时群信息回复包
     *
     * @param packet
     */
    private void processClusterGetTempClusterInfoReply(
            ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("成功得到群信息，群内部ID：" + packet.clusterId + " 群名称：" + packet.info.name);
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_GET_TEMP_INFO_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("得到群信息失败");
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_GET_TEMP_INFO_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理激活群回复包
     *
     * @param packet
     */
    private void processClusterActivateReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("群激活成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_ACTIVATE_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("群激活失败");
            ClusterCommandPacket ccp = (ClusterCommandPacket) policy.retrieveSent(packet);
            packet.clusterId = ccp.getClusterId();
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_ACTIVATE_FAIL;
            client.fireQQEvent(e);
        }
    }

    // 处理创建群回复包
    private void processClusterCreateReply(ClusterCommandReplyPacket packet) {
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("群创建成功，内部ID：" + packet.clusterId + " 外部ID：" + packet.externalId);
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_CREATE_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("群创建失败");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.CLUSTER_CREATE_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理上传下载备注的回复包
     *
     * @param in
     */
    private void processFriendDataOpReply(_08BasicInPacket in) {
        _08QQEvent e;
        FriendDataOpReplyPacket packet = (FriendDataOpReplyPacket) in;
        // 判断操作类型
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            switch (packet.subCommand) {
                case _08QQ.QQ_SUB_CMD_BATCH_DOWNLOAD_FRIEND_REMARK:
                    log.debug("批量下载好友备注信息成功");
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.FRIEND_GET_REMARKS_OK;
                    client.fireQQEvent(e);
                    break;
                case _08QQ.QQ_SUB_CMD_UPLOAD_FRIEND_REMARK:
                    log.debug("上传好友备注信息成功");
                    e = new _08QQEvent(policy.retrieveSent(packet));
                    e.type = _08QQEvent.FRIEND_UPLOAD_REMARKS_OK;
                    client.fireQQEvent(e);
                    break;
                case _08QQ.QQ_SUB_CMD_REMOVE_FRIEND_FROM_LIST:
                    log.debug("更新服务器端好友列表成功");
                    e = new _08QQEvent(policy.retrieveSent(packet));
                    e.type = _08QQEvent.FRIEND_REMOVE_FROM_LIST_OK;
                    client.fireQQEvent(e);
                    break;
                case _08QQ.QQ_SUB_CMD_DOWNLOAD_FRIEND_REMARK:
                    log.debug("下载好友备注信息成功");
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.FRIEND_GET_REMARK_OK;
                    client.fireQQEvent(e);
                    break;
            }
        }
    }

    /**
     * 处理下载分组好友列表回复包
     *
     * @param in
     */
    private void processDownloadGroupFriendReply(_08BasicInPacket in) {
        _08QQEvent e;
        DownloadGroupFriendReplyPacket packet = (DownloadGroupFriendReplyPacket) in;
        policy.retrieveSent(packet);
        // 触发事件
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("下载分组好友列表成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.FRIEND_DOWNLOAD_GROUPS_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("下载分组好友失败");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.FRIEND_DOWNLOAD_GROUPS_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理上传分组名称回复包
     *
     * @param in
     */
    private void processGroupNameOpReply(_08BasicInPacket in) {
        _08QQEvent e;
        GroupDataOpReplyPacket packet = (GroupDataOpReplyPacket) in;
        // 触发事件
        policy.retrieveSent(packet);
        if (packet.subCommand == _08QQ.QQ_SUB_CMD_UPLOAD_GROUP_NAME) {
            log.debug("上传分组名称成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.FRIEND_UPDATE_GROUP_NAMES_OK;
            client.fireQQEvent(e);
        } else if (packet.subCommand == _08QQ.QQ_SUB_CMD_DOWNLOAD_GROUP_NAME) {
            log.debug("下载分组名称成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.FRIEND_GET_GROUP_NAMES_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("未知的分组名称操作类型，忽略该包");
        }
    }

    /**
     * 处理上传分组好友列表回复包
     *
     * @param in
     */
    private void processUploadGroupFriendReply(_08BasicInPacket in) {
        _08QQEvent e;
        UploadGroupFriendReplyPacket packet = (UploadGroupFriendReplyPacket) in;
        // 触发事件
        policy.retrieveSent(packet);
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("上传分组好友列表成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.FRIEND_UPLOAD_GROUPS_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("上传分组好友列表失败");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.FRIEND_UPLOAD_GROUPS_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理搜索在线用户的回复包
     *
     * @param in
     */
    private void processSearchUserReply(_08BasicInPacket in) {
        _08QQEvent e;
        SearchUserReplyPacket packet = (SearchUserReplyPacket) in;

        // 触发事件
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.USER_SEARCH_OK;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理删除自己的回复包
     *
     * @param in
     */
    private void processRemoveSelfReply(_08BasicInPacket in) {
        _08QQEvent e;
        RemoveSelfReplyPacket packet = (RemoveSelfReplyPacket) in;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            log.debug("已经从对方好友列表中删除了自己");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.FRIEND_REMOVE_SELF_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("从对方好友列表中删除自己失败");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.FRIEND_REMOVE_SELF_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理修改个人信息的回复包
     *
     * @param in
     */
    private void processModifyInfoReply(_08BasicInPacket in) {
        _08QQEvent e;
        _08ModifyInfoReplyPacket packet = (_08ModifyInfoReplyPacket) in;
        if (packet.success) {
            log.debug("修改信息成功");
            // 设置用户的新的信息
            _08ModifyInfoPacket miPacket = (_08ModifyInfoPacket) policy.retrieveSent(packet);
            user.setContactInfo(miPacket.getContactInfo());
            e = new _08QQEvent(miPacket);
            e.type = _08QQEvent.USER_MODIFY_INFO_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("修改信息失败");
            e = new _08QQEvent(policy.retrieveSent(packet));
            e.type = _08QQEvent.USER_MODIFY_INFO_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理发送认证信息的回复包
     *
     * @param in
     * @throws PacketParseException
     */
    private void processAddFriendAuthReply(_08BasicInPacket in) {
        _08QQEvent e;
        AddFriendAuthResponseReplyPacket packet = (AddFriendAuthResponseReplyPacket) in;
        if (packet.replyCode != _08QQ.QQ_REPLY_ADD_FRIEND_AUTH_OK) {
            log.debug("认证信息发送失败");
            e = new _08QQEvent(policy.retrieveSent(packet));
            e.type = _08QQEvent.FRIEND_AUTH_SEND_FAIL;
            client.fireQQEvent(e);
        } else {
            log.debug("认证信息发送成功，等待对方回复");
            e = new _08QQEvent(policy.retrieveSent(packet));
            e.type = _08QQEvent.FRIEND_AUTH_SEND_OK;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理删除好友的回复包
     *
     * @param in
     */
    private void processDeleteFriendReply(_08BasicInPacket in) {
        _08QQEvent e;
        DeleteFriendReplyPacket packet = (DeleteFriendReplyPacket) in;
        if (packet.replyCode != _08QQ.QQ_REPLY_OK) {
            log.debug("好友删除失败");
            e = new _08QQEvent(policy.retrieveSent(packet));
            e.type = _08QQEvent.FRIEND_DELETE_FAIL;
            client.fireQQEvent(e);
        } else {
            log.debug("好友删除成功");
            e = new _08QQEvent(policy.retrieveSent(packet));
            e.type = _08QQEvent.FRIEND_DELETE_OK;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理请求加一个好友的回复包
     *
     * @param in
     */
    private void processAddFriendExReply(_08BasicInPacket in) {
        _08QQEvent e;
        AddFriendExReplyPacket packet = (AddFriendExReplyPacket) in;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            switch (packet.authCode) {
                case _08QQ.QQ_AUTH_NO:
                    log.debug("好友添加成功");
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.FRIEND_ADD_OK;
                    client.fireQQEvent(e);
                    break;
                case _08QQ.QQ_AUTH_NEED:
                    log.debug("对方要求认证");
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.FRIEND_ADD_NEED_AUTH;
                    client.fireQQEvent(e);
                    break;
                case _08QQ.QQ_AUTH_REJECT:
                    log.debug("对方禁止别人加他为好友");
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.FRIEND_ADD_DENY;
                    client.fireQQEvent(e);
                    break;
            }
        } else if (packet.replyCode == _08QQ.QQ_REPLY_ADD_FRIEND_ALREADY) {
            log.debug("对方已经是自己的好友");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.FRIEND_ADD_ALREADY;
            client.fireQQEvent(e);
        } else {
            log.debug("添加好友失败");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.FRIEND_ADD_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理系统消息，比如谁谁谁添加你为好友
     *
     * @param in
     */
    private void processSystemNotification(_08BasicInPacket in) {
        _08QQEvent e = null;
        SystemNotificationPacket packet = (SystemNotificationPacket) in;
        // 判断类型
        switch (packet.type) {
            case _08QQ.QQ_SYS_BEING_ADDED:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.SYS_ADDED_BY_OTHERS;
                break;
            case _08QQ.QQ_SYS_ADD_FRIEND_REQUEST:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.SYS_REQUEST_ADD;
                break;
            case _08QQ.QQ_SYS_ADD_FRIEND_APPROVED:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.SYS_APPROVE_ADD;
                break;
            case _08QQ.QQ_SYS_ADD_FRIEND_REJECTED:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.SYS_REJECT_ADD;
                break;
            case _08QQ.QQ_SYS_BEING_ADDED_EX:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.SYS_ADDED_BY_OTHERS_EX;
                break;
            case _08QQ.QQ_SYS_ADD_FRIEND_REQUEST_EX:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.SYS_REQUEST_ADD_EX;
                break;
            case _08QQ.QQ_SYS_ADD_FRIEND_APPROVED_AND_ADD:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.SYS_APPROVE_ADD_BIDI;
                break;
            default:
                log.debug("未知类型的系统通知，忽略");
                break;
        }
        // 触发事件
        if (e != null) {
            client.fireQQEvent(e);
        }
    }

    /**
     * @param in
     * @deprecated 处理未知命令，没有实际操作，简单打印内容
     */
    private void processRequestKeyReply(_08BasicInPacket in) {
        GetKeyReplyPacket packet = (GetKeyReplyPacket) in;
        _08QQEvent e;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.USER_REQUEST_KEY_OK;
            client.fireQQEvent(e);
        } else {
            e = new _08QQEvent(policy.retrieveSent(packet));
            e.type = _08QQEvent.USER_REQUEST_KEY_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理收到的消息
     *
     * @param in
     */
    private void processReceiveIM(_08BasicInPacket in) {
        _08QQEvent e = null;
        log.debug("in的对象是否为空：" + in);
        if (!(in instanceof ReceiveIMPacket)) {
            return;
        }
        ReceiveIMPacket packet = (ReceiveIMPacket) in;
        if (packet.isDuplicated()) {
            log.debug("收到一条重复消息，发送确认");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.IM_DUPLICATED;
            client.fireQQEvent(e);
            return;
        }
        if (packet.flag != 0) {

            log.debug("用户正在输入信息");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.INPUT_STATUS;
            client.fireQQEvent(e);
            return;
        }

        log.debug("崩溃的位置是这里，包的头类型是：" + Util.convertByteToHexString(Util.convertCharToBytes(packet.header.type)));
        // 开始处理
        switch (packet.header.type) {

            case _08QQ.QQ_RECV_IM_FRIEND:
            case _08QQ.QQ_RECV_IM_STRANGER:
            case _08QQ.QQ_RECV_IM_FRIEND_EX:
                e = new _08QQEvent(packet);
                switch (packet.normalHeader.type) {
                    case _08QQ.QQ_IM_TYPE_TEXT:
                        log.debug("普通文本消息被触发！");
                        e.type = _08QQEvent.IM_RECEIVED;
                        break;
                    case _08QQ.QQ_IM_TYPE_UDP_REQUEST:
                        /*log.debug("对方请求传送文件，协议UDP" + " 传送文件端口：" +
                        packet.fileArgs.majorPort);
                        e.type = _08QQEvent.FILE_REQUEST_SEND_TO_ME;*/
                        log.debug("一个尚待处理的命令");
                        break;
                    case _08QQ.QQ_IM_TYPE_REJECT_UDP_REQUEST:
                        log.debug("对方拒绝了传送文件的请求");
                        e.type = _08QQEvent.FILE_REJECT;
                        break;
                    case _08QQ.QQ_IM_TYPE_ACCEPT_UDP_REQUEST:
                        log.debug("对方接受了传送文件的请求");
                        e.type = _08QQEvent.FILE_ACCEPT;
                        break;
                    case _08QQ.QQ_IM_TYPE_NOTIFY_IP:
                        log.debug("对方告诉我文件发送的IP和端口，其外部IP为" + Util.getIpStringFromBytes(packet.fileArgs.internetIp) + " 其外部端口为" + packet.fileArgs.internetPort + " 其主端口为" + packet.fileArgs.majorPort + " 其真实IP为" + Util.getIpStringFromBytes(packet.fileArgs.localIp) + " 其副端口为" + packet.fileArgs.minorPort);
                        e.type = _08QQEvent.FILE_NOTIFY_ARGS;
                        break;
                    case _08QQ.QQ_IM_TYPE_ARE_YOU_BEHIND_FIREWALL:
                        log.debug("对方请求自己主动连接他");
                        e.type = _08QQEvent.FILE_REQUEST_ME_CONNECT;
                        break;
                    case _08QQ.QQ_IM_TYPE_REQUEST_CANCELED:
                        log.debug("对方取消了文件传送");
                        e.type = _08QQEvent.FILE_CANCEL;
                        break;
                    default:
                        log.debug("接受到一条非文本消息，目前无法处理，忽略该消息");
                        e.type = _08QQEvent.IM_UNKNOWN_TYPE_RECEIVED;
                        break;
                }
                break;
            case _08QQ.QQ_RECV_IM_SYS_MESSAGE:
                log.debug("接收到一条系统消息: " + packet.sysMessage);
                if (packet.systemMessageType == _08QQ.QQ_RECV_IM_KICK_OUT) {
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.SYS_KICKED;
                } else {
                    e = new _08QQEvent(packet);
                    e.type = _08QQEvent.SYS_BROADCAST_RECEIVED;
                }
                break;
            case _08QQ.QQ_RECV_IM_CLUSTER:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.IM_CLUSTER_RECEIVED;
                break;
            case _08QQ.QQ_RECV_IM_TEMP_CLUSTER:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.IM_TEMP_CLUSTER_RECEIVED;
                break;
            case _08QQ.QQ_RECV_IM_UNKNOWN_CLUSTER:
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.IM_UNKNOWN_CLUSTER_TYPE_RECEIVED;
                break;
            case _08QQ.QQ_RECV_IM_BIND_USER:
            case _08QQ.QQ_RECV_IM_MOBILE_QQ:
            case _08QQ.QQ_RECV_IM_MOBILE_QQ_2:
            case _08QQ.QQ_RECV_IM_MOBILE:
                log.debug("收到一条短信: " + packet.sms.message);
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.SMS_RECEIVED;
                break;
            case _08QQ.QQ_RECV_IM_TEMP_SESSION:
                log.debug("收到一条临时会话消息: " + packet.tempSessionIM.message);
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.IM_TEMP_SESSION_RECEIVED;
                break;
            case _08QQ.QQ_RECV_IM_CREATE_CLUSTER:
            case _08QQ.QQ_RECV_IM_ADDED_TO_CLUSTER:
                log.debug("收到群创建通知");
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.CLUSTER_ADDED_TO;
                break;
            case _08QQ.QQ_RECV_IM_DELETED_FROM_CLUSTER:
                log.debug("我被创建者从群中删除");
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.CLUSTER_REMOVED_FROM;
                break;
            case _08QQ.QQ_RECV_IM_APPROVE_JOIN_CLUSTER:
                log.debug("对方同意我加入群，附加消息为：" + packet.message);
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.CLUSTER_APPROVE_JOIN;
                break;
            case _08QQ.QQ_RECV_IM_REJECT_JOIN_CLUSTER:
                log.debug("对方拒绝我加入群，附加消息为：" + packet.message);
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.CLUSTER_REJECT_JOIN;
                break;
            case _08QQ.QQ_RECV_IM_REQUEST_JOIN_CLUSTER:
                log.debug("对方请求加入我的群，附加消息为：" + packet.message);
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.CLUSTER_JOIN;
                break;
            case _08QQ.QQ_RECV_IM_CLUSTER_NOTIFICATION:
                switch (packet.opCode) {
                    case _08QQ.QQ_CLUSTER_OP_SET_ADMIN:
                        e = new _08QQEvent(packet);
                        e.type = _08QQEvent.CLUSTER_ADMIN_ENTITLED;
                        break;
                    case _08QQ.QQ_CLUSTER_OP_UNSET_ADMIN:
                        e = new _08QQEvent(packet);
                        e.type = _08QQEvent.CLUSTER_ADMIN_WITHDRAWED;
                        break;
                }
                break;
            case _08QQ.QQ_RECV_IM_SIGNATURE_CHANGE:
                log.debug("好友" + packet.signatureOwner + "的个性签名改变了");
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.FRIEND_SIGNATURE_CHANGED;
                break;
            case _08QQ.QQ_RECV_IM_MEMBER_LOGIN_HINT:
                log.debug("收到会员登录提示");
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.USER_MEMBER_LOGIN_HINT_RECEIVED;
                break;
            case _08QQ.QQ_RECV_IM_PROPERTY_CHANGE:
                log.debug("收到好友属性变化通知");
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.FRIEND_PROPERTY_CHANGED;
                break;
            case _08QQ.QQ_RECV_IM_CUSTOM_HEAD_CHANGE:
                log.debug("收到好友自定义头像改变通知");
                e = new _08QQEvent(packet);
                e.type = _08QQEvent.FRIEND_CUSTOM_HEAD_CHANGED;
                break;
            default:
                log.debug("接收到一条未知类型消息: " + ((int) packet.header.type) + "，目前无法处理，忽略");
                break;
        }

        // fire event
        if (e != null) {
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理Keep Alive的回复事件
     *
     * @param in
     */
    private void processKeepAliveReply(_08BasicInPacket in) {
        _08QQEvent e;
        _08KeepAliveReplyPacket packet = (_08KeepAliveReplyPacket) in;
        if (log.isDebugEnabled()) {
            log.debug("Keep Alive: 在线数: " + packet.onlines + "我的IP: " + Util.convertIpToString(packet.ip));
        }

        // 触发事件
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.USER_KEEP_ALIVE_OK;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理发送消息回复事件
     *
     * @param in
     */
    private void processSendIMReply(_08BasicInPacket in) {
        _08QQEvent e;
        SendIMReplyPacket packet = (SendIMReplyPacket) in;
        if (packet.replyCode == _08QQ.QQ_REPLY_OK) {
            SendIMPacket srcPacket = (SendIMPacket) policy.retrieveSent(packet);
            char messageType = srcPacket.getMessageType();
            if (messageType == _08QQ.QQ_IM_TYPE_TEXT) {
                log.debug("消息发送成功");
                e = new _08QQEvent(srcPacket);
                e.type = _08QQEvent.IM_SEND_OK;
                client.fireQQEvent(e);
            } else if (messageType == _08QQ.QQ_IM_TYPE_UDP_REQUEST) {
                log.debug("传送文件请求已发送，等待对方接受");
                e = new _08QQEvent(srcPacket);
                e.type = _08QQEvent.FILE_SEND_REQUEST_OK;
                client.fireQQEvent(e);
            } else if (messageType == _08QQ.QQ_IM_TYPE_NOTIFY_IP) {
                log.debug("IP信息已发送，等待对方返回确认");
            }
        }
    }

    /**
     * 处理得到在线好友回复事件
     *
     * @param in
     */
    private void processGetFriendOnlineReply(_08BasicInPacket in) {
        _08QQEvent e;
        _08GetOnlineOpReplyPacket packet = (_08GetOnlineOpReplyPacket) in;

        /*
         * if(log.isDebugEnabled()) { Iterator iter =
         * packet.onlineFriends.iterator(); while(iter.hasNext()) { FriendStatus
         * fs = ((FriendOnlineEntry)iter.next()).status; log.debug("好友" +
         * fs.qqNum + "在线状态" + Utils.getStatusString(fs.status)); } }
         */

        e = new _08QQEvent(packet);
        e.type = _08QQEvent.FRIEND_GET_ONLINE_OK;
        client.fireQQEvent(e);
    }

    /**
     * 处理得到好友列表回复事件
     *
     * @param in
     */
    private void processGetFriendListReply(_08BasicInPacket in) {
        _08QQEvent e;
        GetFriendListReplyPacket packet = (GetFriendListReplyPacket) in;
        if (log.isDebugEnabled()) {
            Iterator<?> iter = packet.friends.iterator();
            while (iter.hasNext()) {
                QQFriend friend = (QQFriend) iter.next();
                log.debug("得到好友" + friend.qqNum + ", 昵称: " + friend.nick);
            }
        }
        // 触发事件
        e = new _08QQEvent(packet);
        e.type = _08QQEvent.FRIEND_GET_LIST_OK;
        client.fireQQEvent(e);
    }

    /**
     * 处理改变状态回复事件
     *
     * @param in
     */
    private void processChangeStatusReply(_08BasicInPacket in) {
        _08QQEvent e;
        ChangeStatusReplyPacket packet = (ChangeStatusReplyPacket) in;

        // 检查应答码
        if (packet.replyCode == _08QQ.QQ_REPLY_CHANGE_STATUS_OK) {
            log.debug("改变状态成功");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.USER_STATUS_CHANGE_OK;
            client.fireQQEvent(e);
        } else {
            log.debug("改变状态失败");
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.USER_STATUS_CHANGE_FAIL;
            client.fireQQEvent(e);
        }
    }

    /**
     * 处理得到用户信息回复事件
     *
     * @param in
     */
    private void processGetUserInfoReply(_08BasicInPacket in) {
        _08QQEvent e;
        GetUserInfoReplyPacket packet = (GetUserInfoReplyPacket) in;
        /*
         * if(log.isDebugEnabled()) { for(int i = 0; i < _08QQ.QQ_CONTACT_FIELDS;
         * i++) log.debug("用户信息字段" + i + ": " + packet.contactInfo.infos[i]); }
         */
        // 触发成功事件
        e = new _08QQEvent(packet);
        e.type = _08QQEvent.USER_GET_INFO_OK;
        client.fireQQEvent(e);
    }

    /**
     * 处理好友状态改变事件
     *
     * @param in
     */
    private void processFriendChangeStatus(_08BasicInPacket in) {
        _08QQEvent e;
        FriendChangeStatusPacket packet = (FriendChangeStatusPacket) in;
        if (packet.myQQ == 0) {
            log.warn("好友状态改变包中数据有误，忽略该包");
        } else {
            // 触发事件
            e = new _08QQEvent(packet);
            e.type = _08QQEvent.FRIEND_STATUS_CHANGED;
            client.fireQQEvent(e);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see edu.tsinghua.lumaqq.qq.events.IPacketListener#accept(edu.tsinghua.lumaqq.qq.packets._08InPacket)
     */
    public boolean accept(_08InPacket in) {
        return (in.getFamily() & _08QQ.QQ_PROTOCOL_FAMILY_BASIC) != 0;
    }
}
